----------Oliver's Crosswords----------
A 4am crack                  2017-06-22
---------------------------------------

Name: Oliver's Crosswords
Genre: educational
Year: 1990
Publisher: Micrograms Publishing
Platform: Apple ][+ or later
Media: 2 single-sided 5.25-inch disks
OS: custom
Previous cracks: none

                   ~

               Chapter 0
 In Which Various Automated Tools Fail
          In Interesting Ways


COPYA
  no errors, but copy hangs on boot
  with a text screen full of code

Locksmith Fast Disk Backup
  ditto

EDD 4 bit copy (no sync, no count)
  works

Copy ][+ nibble editor
  disk volume is 000, which is unusual,
  but otherwise tracks look normal --
  16-sector, standard address fields,
  standard everything really

Disk Fixer
  all tracks readable
  ProDOS-style bootloader and disk
    catalog, but no "PRODOS" file

Booting my ProDOS hard drive, I can get
a disk catalog.

]PR#7
...

]CAT,S6,D1

/BOOT

 NAME           TYPE  BLOCKS  MODIFIED

 BAD3.4          SYS       7  <NO DATE>
 PI.TITLE        BIN      17  <NO DATE>
 ST.FONT         BIN       5  <NO DATE>
 CR.CWRDS.MAIN   BIN      13  <NO DATE>
 CWRDS           BIN      15  <NO DATE>
 UTL             BIN       8  <NO DATE>
 SETA            BIN      16  <NO DATE>
 SETB            BIN      16  <NO DATE>
 SETC            BIN      18  <NO DATE>
 SETD            BIN      18  <NO DATE>
 SETE            BIN      22  <NO DATE>
 SETF            BIN      21  <NO DATE>

BLOCKS FREE:   97     BLOCKS USED:  183

Usually the first .SYS file is called
"PRODOS", but this disk has "BAD3.4"
instead.

Why didn't COPYA or Locksmith FDB work?
  probably a nibble check in early boot

Why *did* EDD work?
  the nibble check probably isn't very
  strong

Next steps:

  1. Find the protection check and
     disable it
  2. Declare victory (*)

(*) go to the gym

                   ~

               Chapter 1
      In Which We Take A Shortcut
   That Turns Out To Be Not So Short


The fastest way to find a runtime
protection check is to search for the
instruction that turns on the drive
motor. Generally this is "LDA $C089,X"
(following the convention that the X
register contains the boot slot x 16),
but it could also be hard-coded to
slot 6 like "LDA $C0E9" or some other
variant.

[Disk Fixer]
  ["F"]ind
    ["H"]ex
      "BD 89 C0"

One match, on T00,S0E, which is part of
the ProDOS-style bootloader. No other
matches anywhere, which is odd.

-->   "AD E9 C0"

No matches whatsoever. WTF. Maybe it's
encrypted to prevent exactly the thing
I'm trying to do right now?

Let's try searching for the instruction
that loads the data latch to fetch a
single nibble from disk: "LDA $C08C,X".

-->   "BD 8C C0"

Again, just the one match on T00,S0E.
This is looking less and less like a
shortcut. Maybe the hard-coded variant
"LDA $C0EC"? After that I'm out of
ideas and I'm going to trace the boot
from the beginning.

-->   "AD EC C0"

                 --v--

------------- DISK SEARCH -------------

$01/$0B-$1E   $01/$0B-$27   $01/$0B-$30
$01/$0C-$5E   $01/$0C-$67   $01/$0C-$70
$01/$0C-$80   $01/$0C-$88   $01/$0C-$C3
$01/$0C-$CC   $01/$0C-$D5

                 --^--

Praise be. Let's see what we found.
(Side note: according to Copy II Plus
"disk map," this code is in that
mysterious "BAD3.4" .SYS file.)

                 --v--

T01,S0C
----------- DISASSEMBLY MODE ----------
; match address prologue ($D5 $AA $96)
0050:A9 00          LDA   #$00
0052:85 FC          STA   $FC
0054:88             DEY
0055:D0 07          BNE   $005E
0057:C6 FC          DEC   $FC
0059:D0 03          BNE   $005E
005B:20 C5 09       JSR   $09C5
005E:AD EC C0       LDA   $C0EC
0061:10 FB          BPL   $005E
0063:C9 D5          CMP   #$D5
0065:D0 ED          BNE   $0054
0067:AD EC C0       LDA   $C0EC
006A:10 FB          BPL   $0067
006C:C9 AA          CMP   #$AA
006E:D0 EE          BNE   $005E
0070:AD EC C0       LDA   $C0EC
0073:10 FB          BPL   $0070
0075:C9 96          CMP   #$96
0077:D0 E5          BNE   $005E

; parse address field and store it in
; $082C+ (instead of zero page)
0079:A0 03          LDY   #$03
007B:A9 00          LDA   #$00
007D:8D 2B 08       STA   $082B
0080:AD EC C0       LDA   $C0EC
0083:10 FB          BPL   $0080
0085:2A             ROL
0086:85 F9          STA   $F9
0088:AD EC C0       LDA   $C0EC
008B:10 FB          BPL   $0088
008D:25 F9          AND   $F9
008F:99 2C 08       STA   $082C,Y
0092:4D 2B 08       EOR   $082B
0095:88             DEY
0096:10 E5          BPL   $007D
0098:A8             TAY
0099:D0 AD          BNE   $0048

; looks like we're checking the track
; to see if it's the right one, and
; recalibrating if it's not (DOS 3.3
; does this too but not inline)
009B:AD 2E 08       LDA   $082E
009E:C5 EB          CMP   $EB
00A0:F0 0B          BEQ   $00AD
00A2:0A             ASL
00A3:85 ED          STA   $ED
00A5:A5 EB          LDA   $EB
00A7:20 31 0A       JSR   $0A31
00AA:4C D2 08       JMP   $08D2
00AD:AD 2D 08       LDA   $082D
00B0:C5 EC          CMP   $EC
00B2:D0 94          BNE   $0048
00B4:60             RTS

; separate entry point for reading the
; data prologue and data field
00B5:A9 00          LDA   #$00
00B7:85 FC          STA   $FC
00B9:88             DEY
00BA:D0 07          BNE   $00C3
00BC:C6 FC          DEC   $FC
00BE:D0 03          BNE   $00C3
00C0:20 C5 09       JSR   $09C5

; match data prologue $D5 $AA $AD
00C3:AD EC C0       LDA   $C0EC
00C6:10 FB          BPL   $00C3
00C8:C9 D5          CMP   #$D5
00CA:D0 ED          BNE   $00B9
00CC:AD EC C0       LDA   $C0EC
00CF:10 FB          BPL   $00CC
00D1:C9 AA          CMP   #$AA
00D3:D0 EE          BNE   $00C3
00D5:AD EC C0       LDA   $C0EC
00D8:10 FB          BPL   $00D5
00DA:C9 AD          CMP   #$AD
00DC:D0 E5          BNE   $00C3

; 6-and-2 decoding
00DE:A9 00          LDA   #$00
00E0:A2 56          LDX   #$56
00E2:AC EC C0       LDY   $C0EC
00E5:10 FB          BPL   $00E2
00E7:59 00 0C       EOR   $0C00,Y
00EA:CA             DEX
00EB:9D 00 0C       STA   $0C00,X
00EE:D0 F2          BNE   $00E2
00F0:AC EC C0       LDY   $C0EC
00F3:10 FB          BPL   $00F0
00F5:59 00 0C       EOR   $0C00,Y
00F8:9D 00 0F       STA   $0F00,X
00FB:E8             INX
00FC:D0 F2          BNE   $00F0
00FE:AC EC C0       LDY   $C0EC

[continued on T01,S0B]

0001:10 FB          BPL   $FFFE
0003:59 00 0C       EOR   $0C00,Y
0006:F0 02          BEQ   $000A
0008:38             SEC
0009:60             RTS

; separate entry point for epilogue
; checking
000A:A9 00          LDA   #$00
000C:85 FC          STA   $FC
000E:88             DEY
000F:D0 0D          BNE   $001E
0011:C6 FC          DEC   $FC
0013:D0 09          BNE   $001E

; turn on text page 2, which is not
; something you generally see inside
; RWTS code (this might be where my
; non-working copy ended up)
0015:2C 51 C0       BIT   $C051
0018:2C 55 C0       BIT   $C055
001B:4C A5 09       JMP   $09A5

; match standard epilogue ($DE $AA)
001E:AD EC C0       LDA   $C0EC
0021:10 FB          BPL   $001E
0023:C9 DE          CMP   #$DE
0025:D0 E7          BNE   $000E
0027:AD EC C0       LDA   $C0EC
002A:10 FB          BPL   $0027
002C:C9 AA          CMP   #$AA
002E:D0 EE          BNE   $001E

; match... a third epilogue nibble?!?
0030:AD EC C0       LDA   $C0EC
0033:10 FB          BPL   $0030
0035:C9 BE          CMP   #$BE
0037:D0 E5          BNE   $001E
0039:18             CLC
003A:60             RTS

                 --^--

Oh wow. That's not what I was expecting
at all, but that's the problem. There
is no protection check. The protection
is purely structural -- this RWTS code
is super-strict and requires a third
(non-standard) epilogue nibble.

Technically, both the address epilogue
and the data epilogue are three nibbles
$DE $AA $EB. But even standard DOS 3.3
never checks more than the first two.
(ProDOS only checks the first one.)
Literally nothing checks the third
nibble of the epilogue.

Except this disk.

And it's non-standard ($BE instead of
$EB).

So the disk looks like it's unprotected
(even copies with COPYA), but the copy
can't read itself because the third
epilogue nibble is wrong.

The solution is to patch this RWTS so
it ignores the third epilogue nibble.
The least invasive way to do that is to
change the "BNE" after "CMP #$BE" so it
branches to the next instruction,
effectively making it a NOP.

T01,S0B,$38: E5 -> 00

]PR#6
...works...

Disk 2 has identical proteection.

Quod erat liberandum.

---------------------------------------
A 4am crack                    No. 1269
------------------EOF------------------
